package org.ualr.cpsc.server;

import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable
public class Photo {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id;
    
    @Persistent
    private String user_email;
    @Persistent
    private String user_id;
    @Persistent
    private Date addition;
    @Persistent
    private Date modification;
    
    @Persistent
    private Set<String> tags;
    @Persistent
    private double rating = 0;
    @Persistent
    private Map<String, Integer> ratings;
    @Persistent
    private boolean isPublic;
    @Persistent
    private String url;
    @Persistent
    private final String uuid;
    @Persistent
    private int width;
    @Persistent
    private int height;
    
    public Photo() {
        uuid = UUID.randomUUID().toString();
    }
    
    public String getUUID() {
        return uuid;
    }
    
    public Long getId() {
        return id;
    }
    
    public String getUserEmail() {
        return user_email;
    }
    
    public String getUserId() {
        return user_id;
    }
    
    public Date getAdditionDate() {
        return addition;
    }
    
    public Date getModificationDate() {
        return modification;
    }
    
    public Set<String> getTags() {
        return Collections.unmodifiableSet(tags);
    }
    
    public double getRating() {
        return rating;
    }
    
    public Map<String, Integer> getRatings() {
        return Collections.unmodifiableMap(ratings);
    }
    
    public boolean isPublic() {
        return isPublic;
    }
    
    public String getUrl() {
        return url;
    }
    
    public void setId(Long id) {
        this.id = id;
    }
    
    public void setUserEmail(String user_email) {
        this.user_email = user_email;
    }
    
    public void setUserId(String user_id) {
        this.user_id = user_id;
    }
    
    public void setAdditionDate(Date addition) {
        this.addition = addition;
    }
    
    public void setModificationDate(Date modification) {
        this.modification = modification;
    }
    
    public void setPublic(boolean isPublic) {
        this.isPublic = isPublic;
    }
    
    public void setUrl(String url) {
        this.url = url;
    }
    
    public void addTag(String tag) {
        tags.add(DataStore.sluggifyTag(tag));
    }
    
    public void removeTag(String tag) {
        tags.remove(DataStore.sluggifyTag(tag));
    }
    
    public boolean hasTag(String tag) {
        return tags.contains(DataStore.sluggifyTag(tag));
    }
    
    public void addRating(int rating) {
        ratings.put(DataStore.getUserEmail(), rating);
        this.rating = getAverageRating();
    }
    
    public int getHeight() {
        return height;
    }
    
    public void setHeight(int height) {
        this.height = height;
    }
    
    public int getWidth() {
        return width;
    }
    
    public void setWidth(int width) {
        this.width = width;
    }
    
    public int getAspectHeight(int width, int height) {
        return (int) (this.height * getAspect(width, height));
    }
    
    public int getAspectWidth(int width, int height) {
        return (int) (this.width * getAspect(width, height));
    }
    
    private double getAverageRating() {
        if (ratings.size() == 0) {
            return -1;
        }
        long total = 0;
        for (int rating: ratings.values()) {
            total += rating;
        }
        return (double) total / (double) ratings.size();
    }
    
    private double getAspect(int width, int height) {
        double aspect = (double) width / this.width;
        if (aspect * this.height > height) {
            aspect = (double) height / this.height;
        }
        return aspect;
    }
}